#include "device.h"
#include "modbus.h"
#include <intrins.h>

uchar data server_address = 0xFF;   // 设备地址

// 读取地址
void Read_Address()
{
    server_address  = 0x0D;        // ((P3 & 0x04) >> 2) + 0x0D;
}

// Peripheral specific initialization functions,
// Called from the Init_Device() function PCA0modul0使用定时器4溢出
void PCA0_Init()
{
    //使用定时器0溢出
    PCA0CN    = 0x40;
    PCA0MD    &= ~0x40;
    PCA0MD    = 0x04;//0a-使用外部
    // PCA0CPM0  = 0x46;
    // PCA0CPM1  = 0x46;
    PCA0CPH0  = 0x80;
    PCA0CPH1  = 0x80;
}

void PCA1_Init()
{
    SFRPAGE   = ACTIVE2_PAGE;
    PCA1CN    = 0x40;
    PCA1MD    = 0x01;
    PCA1CPM6  = 0x48;
    PCA1CPM7  = 0x48;
    SFRPAGE   = ACTIVE_PAGE;
}

void Timer_Init()
{
    TMOD      = 0x02;
    CKCON     = 0x04;
    TH0       = T0_RELOAD;
    TR0       = 1;

    SFRPAGE   = ACTIVE2_PAGE;
    TMR4CN    = 0x02;
    TMR4CF    = 0x01;
    TMR4CAPH  = 0xFF;
#if (PCB_VERSION == PCB_A2)
    TMR4CAPL  = 0xF8;
#else
    TMR4CAPL  = 0xE0;
#endif
    TMR4L     = TMR4CAPL;
    TMR4H     = TMR4CAPH;
    TMR5CN    = 0x02;
    TMR5CF    = 0x01;
    TMR5CAPH  = 0xFF;
#if (PCB_VERSION == PCB_A2)
    TMR5CAPL  = 0xF8;
#else
    TMR5CAPL  = 0xE0;
#endif
    TMR5L     = TMR5CAPL;
    TMR5H     = TMR5CAPH;
    SFRPAGE   = ACTIVE_PAGE;
}

void UART_Init()
{
    SCON0 = 0x10; // SCON0: 8-bit variable bit rate

    SFRPAGE = CONFIG_PAGE;
    //        level of STOP bit is ignored
    //        RX enabled
    //        ninth bits are zeros
    //        clear RI0 and TI0 bits
    #if (SYSCLK / BAUDRATE / 2 / 65536 < 1)
    {
        SBRLH0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 + 0.5) >> 8;
        SBRLL0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 + 0.5);
        SBCON0 = 0x43;
    }
    #elif (SYSCLK / BAUDRATE / 2 / 65536 < 4)
    {
        SBRLH0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 / 4 + 0.5) >> 8;
        SBRLL0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 / 4 + 0.5);
        SBCON0 = 0x41;
    }
    #elif (SYSCLK / BAUDRATE / 2 / 65536 < 12)
    {
        SBRLH0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 / 12 + 0.5) >> 8;
        SBRLL0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 / 12 + 0.5);
        SBCON0 = 0x40;
    }
    #else
    {
        SBRLH0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 / 48 + 0.5) >> 8;
        SBRLL0 = -(ushort)((float)SYSCLK / BAUDRATE / 2 / 48 + 0.5);
        SBCON0 = 0x42;
    }
    #endif
    SFRPAGE = ACTIVE_PAGE;
}
#ifdef  _USES_UART1
void UART1_Init()
{
    SFRPAGE   = ACTIVE2_PAGE;
    SCON1     = 0x50;
    SFRPAGE   = ACTIVE_PAGE;

    #if (SYSCLK / UART1_BAUDRATE / 2 / 256 < 1)
    {
        TH1 = -(ushort)((float)SYSCLK / UART1_BAUDRATE / 2 + 0.5); // 0x96
        CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
        CKCON |= 0x08;
    }
    #elif (SYSCLK / UART1_BAUDRATE / 2 / 256 < 4)
    {
        TH1 = -(ushort)(SYSCLK / UART1_BAUDRATE / 2 / 4 + 0.5);
        CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
        CKCON |= 0x01;
    }
    #elif (SYSCLK / UART1_BAUDRATE / 2 / 256 < 12)
    {
        TH1 = -(ushort)(SYSCLK / UART1_BAUDRATE / 2 / 12 + 0.5);
        CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
    }
    #else
    {
        TH1 = -(ushort)(SYSCLK / UART1_BAUDRATE / 2 / 48 + 0.5);
        CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
        CKCON |= 0x02;
    }
    #endif

    TMOD &= ~0xF0;
    TMOD |= 0x20;
    TL1 = TH1; // init Timer1
    TR1 = 1;
}
#endif

void Port_IO_Init()
{

    // P0.0  -  Skipped,     Open-Drain, Digital
    // P0.1  -  Skipped,     Push-Pull,  Digital
    // P0.2  -  Skipped,     Open-Drain, Analog
    // P0.3  -  Skipped,     Open-Drain, Analog
    // P0.4  -  UART_TX (UART0), Push-Pull,  Digital
    // P0.5  -  UART_RX (UART0), Open-Drain, Digital
    // P0.6  -  Skipped,     Open-Drain, Digital
    // P0.7  -  Skipped,     Open-Drain, Digital

    // P1.0  -  Skipped,     Open-Drain, Digital
    // P1.1  -  Skipped,     Open-Drain, Digital
    // P1.2  -  Skipped,     Open-Drain, Digital
    // P1.3  -  Skipped,     Open-Drain, Digital
    // P1.4  -  Skipped,     Open-Drain, Digital
    // P1.5  -  Skipped,     Open-Drain, Digital
    // P1.6  -  Skipped,     Open-Drain, Digital
    // P1.7  -  Skipped,     Push-Pull,  Digital

    // P2.0  -  Skipped,     Push-Pull,  Digital
    // P2.1  -  Skipped,     Push-Pull,  Digital
    // P2.2  -  Skipped,     Push-Pull,  Digital
    // P2.3  -  Skipped,     Push-Pull,  Digital
    // P2.4  -  CEX0 (PCA0), Push-Pull,  Digital
    // P2.5  -  CEX1 (PCA0), Push-Pull,  Digital
    // P2.6  -  CEX2 (PCA0), Push-Pull,  Digital
    // P2.7  -  T4  (Timr4), Open-Drain, Digital

    // P3.0  -  T5  (Timr5), Open-Drain, Digital
    // P3.1  -  Unassigned,  Open-Drain, Digital
    // P3.2  -  Unassigned,  Open-Drain, Digital
    // P3.3  -  Unassigned,  Open-Drain, Digital
    // P3.4  -  Unassigned,  Push-Pull,  Digital
    // P3.5  -  Unassigned,  Push-Pull,  Digital
    // P3.6  -  Unassigned,  Push-Pull,  Digital
    // P3.7  -  Unassigned,  Push-Pull,  Digital

    // P4.0  -  Unassigned,  Push-Pull,  Digital [Fixed]
    // P4.1  -  Unassigned,  Push-Pull,  Digital [Fixed]
    // P4.2  -  Unassigned,  Push-Pull,  Digital [Fixed]
    // P4.3  -  Unassigned,  Push-Pull,  Digital [Fixed]
    // P4.4  -  Unassigned,  Push-Pull,  Digital [Fixed]
    // P4.5  -  Unassigned,  Push-Pull,  Digital [Fixed]
    // P4.6  -  Unassigned,  Open-Drain, Digital [Fixed]
    // P4.7  -  Unassigned,  Open-Drain, Digital [Fixed]

    SFRPAGE   = CONFIG_PAGE;
    P0MDIN    = 0xF3;
    P0MDOUT   = 0x12;
    P1MDOUT   = 0x80;
    P2MDOUT   = 0x7F;
    P3MDOUT   = 0xF0;
    P4MDOUT   = 0x3F;
    P0SKIP    = 0xCF;
    P1SKIP    = 0xFF;
    P2SKIP    = 0x0F;
    XBR0      = 0x01;
    XBR1      = 0x0C;
    XBR2      = 0x40;
    XBR3      = 0x50;
    SFRPAGE   = ACTIVE_PAGE;
}

void Oscillator_Init()
{
    int i = 0;
    SFRPAGE   = CONFIG_PAGE;
    OSCICN    = 0xC7;
    CLKMUL    = 0x00;
    CLKMUL   |= 0x02;
    CLKMUL   |= 0x10;
    CLKMUL    = 0x80;
    for (i = 0; i < 200; i++);    // Wait 5us for clock multiplier initialization
    CLKMUL    |= 0xC0;
    while ((CLKMUL & 0x20) == 0);
    CLKSEL    = 0x02;
    SFRPAGE   = ACTIVE_PAGE;
}

void Interrupts_Init()
{
    EIE1      = 0x08;
    EIE2      = 0xD8;
    IE        = 0x10;
}

// Initialization function for device,
// Call Init_Device() from your main program
void Init_Device(void)
{
    PCA0_Init();
    PCA1_Init();       // 系统中断定时器初始化
    Timer_Init();      // 电机定时器初始化
    UART_Init();
#ifdef _USES_UART1
    UART1_Init();
#endif
    Port_IO_Init();    // IO端口初始化
    Oscillator_Init(); // 晶振初始化
    Interrupts_Init(); // 中断初始化

    Read_Address();
    IO_Y_STEP = 0;
    IO_Z_STEP = 0;

    // 设置PCB1版本的电机细分，PCB2细分由硬件设置，为16细分
#if (PCB_VERSION == PCB_A1)
    SET_Y_MOTOR_EXCITATION(Y_MOTOR_EXCITATION_64);
    SET_Z_MOTOR_EXCITATION(Z_MOTOR_EXCITATION_64);
#endif

    // 全局中断开启
    EA = 1;
}
